import Debounce from '../types/debounce';
/**
 * @description 防抖
 * @param func {Function} 回调方法
 * @param wait {number} 等待时间
 * @param immediate {boolean} 是否初始化
 * @return {*}
 */
const debounce: Debounce = (func, wait, immediate) => {
    let timeout: any, args: any, context: any, timestamp: any, result: any;

    const later = function () {
        // 据上一次触发时间间隔
        const last = +new Date() - timestamp;

        // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
        if (last < wait && last > 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function (this: any, ...args: any) {
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        context = this;
        timestamp = +new Date();
        const callNow = immediate && !timeout;
        // 如果延时不存在，重新设定延时
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
};

export default debounce;